/*
 * Copyright (c) 2020.
 * http://www.ulabcare.com
 */

package com.mt.roll.passport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mt.roll.core.base.BaseService;
import com.mt.roll.core.dal.entity.LoginLog;
import com.mt.roll.core.dal.entity.LoginSession;
import com.mt.roll.core.dal.entity.SysOrg;
import com.mt.roll.core.dal.service.LoginLogServiceBiz;
import com.mt.roll.core.dal.service.LoginSessionServiceBiz;
import com.mt.roll.core.dal.service.SysOrgServiceBiz;
import com.mt.roll.core.dto.ApiLogDto;
import com.mt.roll.core.dto.LoginLogDto;
import com.mt.roll.core.enums.UserTypeEnum;
import com.mt.roll.core.vo.R;
import com.mt.roll.passport.service.LogService;
import nl.basjes.parse.useragent.UserAgent;
import nl.basjes.parse.useragent.UserAgentAnalyzer;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * @author jiff
 * @date 2019-07-20
 * @since 1.0
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class LogServiceImpl extends BaseService implements LogService {
    @Autowired
    private LoginSessionServiceBiz loginSessionServiceBiz;
    @Autowired
    private LoginLogServiceBiz loginLogServiceBiz;
    @Autowired
    private SysOrgServiceBiz sysOrgServiceBiz;


    private UserAgentAnalyzer uaa = UserAgentAnalyzer
            .newBuilder()
            .withoutCache()
            .hideMatcherLoadStats()
            //            .withField(UserAgent.OPERATING_SYSTEM_NAME)
            .build();

    /**
     * 保存登录日志
     *
     * @param loginLogDto
     * @return
     */
    @Override
    public R<Long> saveLoginLog(LoginLogDto loginLogDto) {
        int action = loginLogDto.getAction();
        //保存登录会话信息
        if (action == LoginLogDto.ACTION_LOGIN) {
            LoginSession loginSession = loginSessionServiceBiz.getOne(new QueryWrapper<LoginSession>().eq(LoginSession.SESSION_ID, loginLogDto.getSessionId()).last("LIMIT 1"));
            if (loginSession == null) {
                loginSession = new LoginSession();
                BeanUtils.copyProperties(loginLogDto, loginSession);
                loginSession.setLoginTime(LocalDateTime.ofInstant(loginLogDto.getLoginTime().toInstant(), ZoneId.systemDefault()));

                if (ObjectUtils.allNotNull(loginLogDto.getOrgId())) {
                    if (loginLogDto.getUserType() == UserTypeEnum.PLATFORM.getValue()) {
                        SysOrg org = sysOrgServiceBiz.getById(loginLogDto.getOrgId());
                        if (org != null) {
                            loginSession.setOrgName(org.getName());
                        }
                    }
                }

                UserAgent userAgent = uaa.parse(loginLogDto.getUserAgent());
                loginSession.setDeviceClass(userAgent.getValue(UserAgent.DEVICE_CLASS))
                        .setDeviceName(userAgent.getValue(UserAgent.DEVICE_NAME))
                        .setDeviceBrand(userAgent.getValue(UserAgent.DEVICE_BRAND))
                        .setOs(userAgent.getValue(UserAgent.OPERATING_SYSTEM_NAME_VERSION))
                        .setBrowser(userAgent.getValue(UserAgent.AGENT_NAME_VERSION));

                loginSession.setCreator(loginLogDto.getUserId())
                        .setCreatorName(loginLogDto.getUserName())
                        .setCreateTime(LocalDateTime.now());
                loginSessionServiceBiz.save(loginSession);
            }
        } else {
            //删除登录会话，保存登录日志
            LoginSession loginSession = loginSessionServiceBiz.getOne(new QueryWrapper<LoginSession>().eq(LoginSession.SESSION_ID, loginLogDto.getSessionId()).last("LIMIT 1"));
            if (loginSession != null) {
                LoginLog loginLog = new LoginLog();
                BeanUtils.copyProperties(loginSession, loginLog);
                loginLog.setLogoutType(loginLogDto.getLogoutType())
                        .setLogoutTime(LocalDateTime.ofInstant(loginLogDto.getLogoutTime().toInstant(), ZoneId.systemDefault()))
                        .setLogoutIp(loginLogDto.getIp())
                        .setLogoutUserAgent(loginLogDto.getUserAgent());
                if (loginLogDto.getLogoutType() == LoginLogDto.LOGOUT_TYPE_MANAGE) {
                    loginLog.setUpdater(loginLogDto.getUserId())
                            .setUpdaterName(loginLogDto.getUserName())
                            .setUpdateTime(LocalDateTime.now());
                } else {
                    loginLog.setUpdater(loginSession.getUserId())
                            .setUpdaterName(loginSession.getUserName())
                            .setUpdateTime(LocalDateTime.now());
                }
                loginSessionServiceBiz.removeById(loginSession.getId());
                loginLogServiceBiz.save(loginLog);
            }
        }
        return successful(null);
    }

    /**
     * 保存接口日志
     *
     * @param apiLogDto
     * @return
     */
    @Override
    public R<Long> saveApiLog(ApiLogDto apiLogDto) {
        return null;
    }
}
